Android 休眠(二)真.永久不休眠

您所在的位置:网站首页 touchpanel screenoff Android 休眠(二)真.永久不休眠

Android 休眠(二)真.永久不休眠

2023-04-15 20:19| 来源: 网络整理| 查看: 265

Platform: RK3288OS: Android 7.1.2Kernel: 4.4.143 

 

adb shell settings get system screen_off_timeout

 一.SettingsProvider def_screen_off_timeout

1.1.frameworks\base\packages\SettingsProvider\res\values\defaults.xml 

欸为什么是0x7fffffff  换算 十进制 是2147483647  

ro.rk.screenoff_time 也是2147483647

整形最大取值就是 2147483647 换算成天数也就是24.85

true 0x7fffffff -1

1.2.frameworks\base\packages\SettingsProvider\src\com\android\providers\settings\DatabaseHelper.java

//add for factory as ro.rk.screenoff_time loadSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT, SystemProperties.getInt("ro.rk.screenoff_time", mContext.getResources().getInteger(R.integer.def_screen_off_timeout)));

1.3.frameworks\base\services\core\java\com\android\server\policy\PhoneWindowManager.java

a.观察 数据库 变化

class SettingsObserver extends ContentObserver { SettingsObserver(Handler handler) { super(handler); } void observe() { // Observe all users' changes …………………………………………………………………………………… resolver.registerContentObserver(Settings.System.getUriFor( Settings.System.SCREEN_OFF_TIMEOUT), false, this, UserHandle.USER_ALL);

b.updateSettings  mLockScreenTimeout

public void updateSettings() { ContentResolver resolver = mContext.getContentResolver(); boolean updateRotation = false; synchronized (mLock) { ……………………………………………………………… // use screen off timeout setting as the timeout for the lockscreen mLockScreenTimeout = Settings.System.getIntForUser(resolver, Settings.System.SCREEN_OFF_TIMEOUT, 0, UserHandle.USER_CURRENT);

c.postDelayed 

private void updateLockScreenTimeout() { synchronized (mScreenLockTimeout) { boolean enable = (mAllowLockscreenWhenOn && mAwake && mKeyguardDelegate != null && mKeyguardDelegate.isSecure(mCurrentUserId)); if (mLockScreenTimerActive != enable) { if (enable) { if (localLOGV) Log.v(TAG, "setting lockscreen timer"); mHandler.removeCallbacks(mScreenLockTimeout); // remove any pending requests mHandler.postDelayed(mScreenLockTimeout, mLockScreenTimeout); } else { if (localLOGV) Log.v(TAG, "clearing lockscreen timer"); mHandler.removeCallbacks(mScreenLockTimeout); } mLockScreenTimerActive = enable; } } }

1.4.frameworks\base\services\core\java\com\android\server\power\PowerManagerService.java

mScreenOffTimeoutSetting = Settings.System.getIntForUser(resolver, Settings.System.SCREEN_OFF_TIMEOUT, DEFAULT_SCREEN_OFF_TIMEOUT, UserHandle.USER_CURRENT);

获取休眠时间

private int getScreenOffTimeoutLocked(int sleepTimeout) { int timeout = mScreenOffTimeoutSetting; if (isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) { timeout = Math.min(timeout, mMaximumScreenOffTimeoutFromDeviceAdmin); } if (mUserActivityTimeoutOverrideFromWindowManager >= 0) { timeout = (int)Math.min(timeout, mUserActivityTimeoutOverrideFromWindowManager); } if (sleepTimeout >= 0) { timeout = Math.min(timeout, sleepTimeout); } return Math.max(timeout, mMinimumScreenOffTimeoutConfig); } 

//根据nextTimeOut延迟发送信息,信息被处理后,将重新调用updatePowerStateLocked,于是再次进入到该方法//通过不断进入该方法,不断评估是否根据用户动作亮、熄屏等

private void updateUserActivitySummaryLocked(long now, int dirty) { if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS | DIRTY_SETTINGS)) != 0) { mHandler.removeMessages(MSG_USER_ACTIVITY_TIMEOUT); long nextTimeout = 0; if (mWakefulness == WAKEFULNESS_AWAKE || mWakefulness == WAKEFULNESS_DREAMING || mWakefulness == WAKEFULNESS_DOZING) { //获取进入休眠状态的时间sleepTimeout //getSleepTimeoutLocked中会判断休眠时间和屏幕熄灭时间的关系 //如果休眠时间sleepTimeout小于屏幕熄灭时间screenOfftime, //则休眠时间被调整为屏幕熄灭时间,因为屏幕亮屏状态下,终端不能进入休眠 final int sleepTimeout = getSleepTimeoutLocked(); //获取屏幕熄灭的时间 final int screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout); //获取屏幕变暗的时间 final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout); …………………………………………………… if (mUserActivitySummary != 0 && nextTimeout >= 0) { Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY_TIMEOUT); msg.setAsynchronous(true); mHandler.sendMessageAtTime(msg, nextTimeout); } } else { mUserActivitySummary = 0; }

 

 二.永久休眠 方案一  WakeLock

 2.1.WakeLock 唤醒锁

a.权限

  

c.WakeLock 常见的锁

WakeLock 分类如下:PARTIAL_WAKE_LOCK: 保持CPU 运转 灭屏 关闭键盘背光的情况下 PROXIMITY_SCREEN_OFF_WAKE_LOCK: 基于距离感应器熄灭屏幕。最典型的运用场景是我们贴近耳朵打电话时,屏幕会自动熄灭SCREEN_DIM_WAKE_LOCK:保持CPU 运转,允许保持屏幕显示但有可能是灰的,允许关闭键盘灯SCREEN_BRIGHT_WAKE_LOCK:保持CPU 运转,允许保持屏幕高亮显示,允许关闭键盘灯FULL_WAKE_LOCK:保持CPU 运转,保持屏幕高亮显示,键盘灯也保持亮度SCREEN_DIM_WAKE_LOCK/SCREEN_BRIGHT_WAKE_LOCK/FULL_WAKE_LOCK:这三种WakeLock都已经过时了 它们的目的是为了保持屏幕长亮 Android官方建议用getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);方式替换 因为比起申请WakeLock 这种方式更简单 还不需要特别申请android.permission.WAKE_LOCK权限DOZE_WAKE_LOCK/DRAW_WAKE_LOCK:隐藏的分类,系统级别才会用到

WakeLock的flag如下:ACQUIRE_CAUSES_WAKEUP:点亮屏幕 比如应用接收到通知后,屏幕亮起。ON_AFTER_RELEASE:释放WakeLock后 屏幕不马上熄灭 保持屏幕亮起一段时间UNIMPORTANT_FOR_LOGGING:隐藏的flag 系统级别才会用到

b.wakeLock.acquire();  wakeLock.release();

package com.gatsby.wakelockservice; import android.app.Service; import android.content.Context; import android.content.Intent; import android.os.IBinder; import android.os.PowerManager; import android.os.PowerManager.WakeLock; import android.util.Log; public class WakeLockService extends Service { private WakeLock wakeLock = null; @Override public IBinder onBind(Intent arg0) { // TODO Auto-generated method stub return null; } @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); acquireWakeLock(); } @Override public void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); Log.d("gatsby","WakeLockService onDestroy"); releaseWakeLock(); } // 获取电源锁 private void acquireWakeLock() { if (null == wakeLock) { PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE); wakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, "gatsby-wakelockService-TAG"); if (null != wakeLock) { wakeLock.acquire(); } } } // 释放设备电源锁 private void releaseWakeLock() { if (null != wakeLock) { wakeLock.release(); wakeLock = null; } } }

d.研究一下 源码 先欢迎 四年级学生森下下士  我们的老大哥  小草凡 Android 功耗分析之wakelock

先跟着老大哥 走了一遍源码   

frameworks/base/core/java/android/os/PowerManager.java acquire--->acquireLocked---->PowerManagerService.acquireWakeLock frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java acquireWakeLock--->acquireWakeLockInternal---->updatePowerStateLocked---->updateSuspendBlockerLocked---->mWakeLockSuspendBlocker.acquire---->PowerManagerService$SuspendBlockerImpl.acquire---->nativeAcquireSuspendBlocker frameworks/base/services/core/jni/com_android_server_power_PowerManagerService.cpp nativeAcquireSuspendBlocker---->acquire_wake_lock

hardware\libhardware_legacy\power\power.c 

12-06 12:10:48.884 457 855 I power : release_wake_lock id='PowerManagerService.WakeLocks' 12-06 12:10:59.157 457 457 I power : acquire_wake_lock lock=1 id='PowerManagerService.WakeLocks' 12-06 12:10:59.193 457 923 I power : release_wake_lock id='PowerManagerService.WakeLocks' 12-06 12:10:59.852 457 568 I power : acquire_wake_lock lock=1 id='PowerManagerService.Broadcasts' 12-06 12:10:59.854 457 568 I power : release_wake_lock id='PowerManagerService.Display' 12-06 12:11:00.347 457 457 I power : release_wake_lock id='PowerManagerService.Broadcasts' 12-06 12:11:04.196 457 587 I power : acquire_wake_lock lock=1 id='PowerManagerService.WakeLocks' 12-06 12:11:04.341 457 457 I power : release_wake_lock id='PowerManagerService.WakeLocks' 12-06 12:11:04.854 457 598 I power : acquire_wake_lock lock=1 id='KeyEvents'

 /sys/power/wake_lock写入节点

acquire_wake_lock(int lock, const char* id) { initialize_fds(); // ALOGI("acquire_wake_lock lock=%d id='%s'\n", lock, id); if (g_error) return g_error; int fd; size_t len; ssize_t ret; if (lock != PARTIAL_WAKE_LOCK) { return -EINVAL; } fd = g_fds[ACQUIRE_PARTIAL_WAKE_LOCK]; ret = write(fd, id, strlen(id)); if (ret < 0) { return -errno; } return ret; } int release_wake_lock(const char* id) { initialize_fds(); // ALOGI("release_wake_lock id='%s'\n", id); if (g_error) return g_error; ssize_t len = write(g_fds[RELEASE_WAKE_LOCK], id, strlen(id)); if (len < 0) { return -errno; } return len; }

龙套三人组:听不见!重来!/根本听不见!再说一遍!/听不见!重来/这么小声还想开军舰! 到了power这里还不算完  

到 android 休眠唤醒机制分析(一) — wake_lock

static struct wake_lock xh_charge_display_lock;// 申请锁 wake_lock_init(&xh_charge_display_lock, WAKE_LOCK_SUSPEND, "xh_charge_display_lock");// WAKE_LOCK_SUSPEND 阻止进入深度休眠模式 wake_lock(&xh_charge_display_lock);//保管锁

2.2.patch

diff --git a/packages/apps/Settings/AndroidManifest.xml b/packages/apps/Settings/AndroidManifest.xml index 52841dd..5764d40 100755 --- a/packages/apps/Settings/AndroidManifest.xml +++ b/packages/apps/Settings/AndroidManifest.xml @@ -86,6 +86,7 @@ + + + + diff --git a/packages/apps/Settings/src/com/android/settings/DisplaySettings.java b/packages/apps/Settings/src/com/android/settings/DisplaySettings.java index 2b52b39..f084af8 100755 --- a/packages/apps/Settings/src/com/android/settings/DisplaySettings.java +++ b/packages/apps/Settings/src/com/android/settings/DisplaySettings.java @@ -110,7 +110,8 @@ public class DisplaySettings extends SettingsPreferenceFragment implements private String mProduct; private ListPreference mDensityListPreference; DisplayMetrics dm; - private String density_olddegree; + private String density_olddegree; + private Intent wakelock_intent; @Override protected int getMetricsCategory() { @@ -469,12 +470,19 @@ public class DisplaySettings extends SettingsPreferenceFragment implements @Override public boolean onPreferenceChange(Preference preference, Object objValue) { final String key = preference.getKey(); - if (KEY_SCREEN_TIMEOUT.equals(key)) { + final Context context = preference.getContext(); + if (KEY_SCREEN_TIMEOUT.equals(key)) { + wakelock_intent = new Intent(context,WakeLockService.class); try { int value = Integer.parseInt((String) objValue); if (value == 0) { value = Integer.MAX_VALUE; - } + context.startService(wakelock_intent); + SystemProperties.set("persist.sys.wakeLock","1"); + }else { + context.stopService(wakelock_intent); + SystemProperties.set("persist.sys.wakeLock","0"); + } Settings.System.putInt(getContentResolver(), SCREEN_OFF_TIMEOUT, value); updateTimeoutPreferenceDescription(value); } catch (NumberFormatException e) { diff --git a/packages/apps/Settings/src/com/android/settings/HdmiReceiver.java b/packages/apps/Settings/src/com/android/settings/HdmiReceiver.java index aff17a5..604997c 100755 --- a/packages/apps/Settings/src/com/android/settings/HdmiReceiver.java +++ b/packages/apps/Settings/src/com/android/settings/HdmiReceiver.java @@ -33,6 +33,11 @@ import android.widget.Toast; import android.os.DisplayOutputManager; import com.android.settings.R; +import android.provider.Settings; +import android.os.Bundle; +import android.content.Intent; +import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT; + public class HdmiReceiver extends BroadcastReceiver { private final String HDMI_ACTION = "android.intent.action.HDMI_PLUG"; private final String BOOT_ACTION="android.intent.action.BOOT_COMPLETED"; @@ -47,6 +52,8 @@ public class HdmiReceiver extends BroadcastReceiver { private SharedPreferences preferences; private File DualModeFile = new File("/sys/class/graphics/fb0/dual_mode"); private DisplayOutputManager mDisplayManagement = null; + private Intent wakelock_intent; + @Override public void onReceive(Context context, Intent intent) { mcontext = context; @@ -125,6 +132,18 @@ public class HdmiReceiver extends BroadcastReceiver { SystemProperties.set("sys.abc_switch", "1"); //InitDualModeTask initDualModeTask=new InitDualModeTask(); //initDualModeTask.execute(); + try { + long screen_off_timeout = Settings.System.getLong(context.getContentResolver(), SCREEN_OFF_TIMEOUT,30000); + boolean enable_wakeLock = (SystemProperties.getInt("persist.sys.wakeLock", 0) == 1); + Log.d("gatsby","HdmiReceiver HdmiReceiver enable_wakeLock ->"+enable_wakeLock); + wakelock_intent = new Intent(context,WakeLockService.class); + if((screen_off_timeout == Integer.MAX_VALUE) && enable_wakeLock){ + Log.d("gatsby","HdmiReceiver HdmiReceiver"); + context.startService(wakelock_intent); + } + }catch (NumberFormatException e) { + Log.e("gatsby", "could not persist screen timeout setting", e); + } } } diff --git a/packages/apps/Settings/src/com/android/settings/WakeLockService.java b/packages/apps/Settings/src/com/android/settings/WakeLockService.java new file mode 100755 index 0000000..8c021cd --- /dev/null +++ b/packages/apps/Settings/src/com/android/settings/WakeLockService.java @@ -0,0 +1,52 @@ +package com.android.settings; + +import android.app.Service; +import android.content.Context; +import android.content.Intent; +import android.os.IBinder; +import android.os.PowerManager; +import android.os.PowerManager.WakeLock; +import android.util.Log; + +public class WakeLockService extends Service { + + private WakeLock wakeLock = null; + + @Override + public IBinder onBind(Intent arg0) { + return null; + } + + @Override + public void onCreate() { + super.onCreate(); + Log.d("gatsby","WakeLockService onCreate"); + acquireWakeLock(); + } + + @Override + public void onDestroy() { + super.onDestroy(); + Log.d("gatsby","WakeLockService onDestroy"); + releaseWakeLock(); + } + + private void acquireWakeLock() { + if (null == wakeLock) { + PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE); + wakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, + "gatsby-wakelockService-TAG"); + if (null != wakeLock) { + wakeLock.acquire(); + } + } + } + + private void releaseWakeLock() { + if (null != wakeLock) { + wakeLock.release(); + wakeLock = null; + } + } + +}

 测试 方法

am startservice -n com.android.settings/com.android.settings.WakeLockService am stopservice -n com.android.settings/com.android.settings.WakeLockService

 查看锁   dumpsys power|grep -i wake

通过adb命令查看WakeLock锁的个数: dumpsys power    uid=1000是系统用户

 

三.永久不休眠 方案二  死循环休眠  

  

 

 

  



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3